package com.sparrow.common.map.vector;

/**
 * 三维向量
 */
public class Vector3 implements Cloneable {
    public float x, y, z;

    // 构造函数
    public Vector3() { this(0, 0, 0); }

    public Vector3(float x, float y, float z) {
        this.x = x; this.y = y; this.z = z;
    }

    public Vector3(Vector3 other) {
        this.x = other.x; this.y = other.y; this.z = other.z;
    }

    // ================= 基础运算 =================
    public Vector3 add(Vector3 v) {
        return new Vector3(this.x + v.x, this.y + v.y, this.z + v.z);
    }

    public Vector3 subtract(Vector3 v) {
        return new Vector3(this.x - v.x, this.y - v.y, this.z - v.z);
    }

    public Vector3 multiply(float scalar) {
        return new Vector3(this.x * scalar, this.y * scalar, this.z * scalar);
    }

    public Vector3 divide(float scalar) {
        if (scalar == 0) throw new ArithmeticException("Divide by zero");
        return new Vector3(this.x / scalar, this.y / scalar, this.z / scalar);
    }

    public Vector3 negate() {
        return new Vector3(-x, -y, -z);
    }

    // ================= 向量属性 =================
    public float length() {
        return (float) Math.sqrt(x*x + y*y + z*z);
    }

    public float lengthSquared() {
        return x*x + y*y + z*z;
    }

    public Vector3 normalize() {
        float len = length();
        if (len == 0) return new Vector3(0,0,0);
        return divide(len);
    }

    public float distance(Vector3 v) {
        return subtract(v).length();
    }

    public float distanceSquared(Vector3 v) {
        return subtract(v).lengthSquared();
    }

    // ================= 点积 / 叉积 =================
    public float dot(Vector3 v) {
        return x*v.x + y*v.y + z*v.z;
    }

    public Vector3 cross(Vector3 v) {
        return new Vector3(
                y*v.z - z*v.y,
                z*v.x - x*v.z,
                x*v.y - y*v.x
        );
    }

    // ================= 插值 =================
    public Vector3 lerp(Vector3 target, float t) {
        return this.multiply(1 - t).add(target.multiply(t));
    }

    // ================= 旋转 =================
    // 绕 Z 轴旋转 (2D 游戏常用)
    public Vector3 rotateZ(float radians) {
        float cos = (float) Math.cos(radians);
        float sin = (float) Math.sin(radians);
        float nx = x * cos - y * sin;
        float ny = x * sin + y * cos;
        return new Vector3(nx, ny, z);
    }

    // ================= 角度计算 =================
    public float angleBetween(Vector3 v) {
        float lenProduct = this.length() * v.length();
        if (lenProduct == 0) return 0;
        float dot = this.dot(v) / lenProduct;
        dot = Math.max(-1f, Math.min(1f, dot)); // Clamp
        return (float) Math.acos(dot); // 弧度
    }

    // ================= 克隆 / 输出 =================
    @Override
    public Vector3 clone() {
        return new Vector3(this);
    }

    @Override
    public String toString() {
        return String.format("Vector3(%.3f, %.3f, %.3f)", x, y, z);
    }

    // ================= 静态常用向量 =================
    public static final Vector3 ZERO = new Vector3(0,0,0);
    public static final Vector3 ONE = new Vector3(1,1,1);
    public static final Vector3 UP = new Vector3(0,1,0);
    public static final Vector3 DOWN = new Vector3(0,-1,0);
    public static final Vector3 LEFT = new Vector3(-1,0,0);
    public static final Vector3 RIGHT = new Vector3(1,0,0);
    public static final Vector3 FORWARD = new Vector3(0,0,1);
    public static final Vector3 BACK = new Vector3(0,0,-1);
}

